﻿using Sustainalytics.CDDB.DataConnector;
using Sustainalytics.Entities.ProductInvolvement;
using Sustainalytics.SharedEntities.Interfaces.Enums;
using Sustainalytics.UrlHelpers;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;

namespace Sustainalytics.ClientDW.Synchronization.SyncProductInvolvement
{
    public class PICddb
    {
        private readonly ResearchFramework _universe;
        private readonly CorporateDataRepository _repository;

        protected PICddb(ResearchFramework universe)
        {
            _universe = universe;

            var thriftServerAddress = ConfigurationManager.AppSettings["HBaseThriftServer"];
            if (String.IsNullOrEmpty(thriftServerAddress))
                throw new ArgumentException("No app setting found for HBaseThriftServer");

            if (!Int32.TryParse(ConfigurationManager.AppSettings["HBaseThriftPort"], out int thriftPort))
                throw new ArgumentException("No app setting found for HBaseThriftPort");

            var hBaseTablePrefix = ConfigurationManager.AppSettings["HBaseTablePrefix"];

            var hiveConnectionString = ConfigurationManager.AppSettings["HiveConnectionString"];
            if (String.IsNullOrEmpty(hiveConnectionString))
                throw new ArgumentException("No app setting found for HiveConnectionString");

            _repository = new CorporateDataRepository(thriftServerAddress, thriftPort, hBaseTablePrefix, hiveConnectionString);
        }

        public static PICddb GetInstance(ResearchFramework universe)
            => new PICddb(universe);

        public List<ProductInvolvementData> GetPICompanies()
        {
            UrlFriendlyGenerator friendlyUrl = new UrlFriendlyGenerator();

            return _repository.ListCompaniesWithActiveResearch(_universe,
                new List<Expression<Func<SharedEntities.Corporate.CorporateDetails, string>>>
                {
                    cd => nameof(cd.Id),
                    cd => nameof(cd.CompanyName),
                    cd => nameof(cd.Country),
                    cd => nameof(cd.SustainalyticsIndustryGroup),
                    cd => nameof(cd.PeerGroup),
                    cd => nameof(cd.MainIdentifiers.ExchangeTicker),
                    cd => nameof(cd.SubPeerGroup),
                    cd => nameof(cd.SubPeerGroupId),
                    cd => nameof(cd.MarketCapitalization),
                    cd => nameof(cd.TotalEmployees),
                    cd => nameof(cd.MainIdentifiers.CompanyExternalId)
                })
                .Where(x => !x.ResearchParentId.HasValue)
                .Select(cd => new ProductInvolvementData
                {
                    Id = cd.Id,
                    CompanyName = cd.CompanyName,
                    Country = cd.Country,
                    Industry = cd.SubPeerGroup,
                    IndustryId = cd.SubPeerGroupId.ToString(),
                    PeerGroupName = cd.PeerGroup,
                    CompanyId = cd.MainIdentifiers.CompanyExternalId,
                    Exchange = GetExchangeTickerSegment(cd.MainIdentifiers.ExchangeTicker, true),
                    Ticker = GetExchangeTickerSegment(cd.MainIdentifiers.ExchangeTicker, false),
                    CompanyNameLowerCase = cd.CompanyName.ToLower(CultureInfo.InvariantCulture),
                    MarketCap = cd.MarketCapitalization,
                    Employees = cd.TotalEmployees,
                    CompanyNameSafeUrl = friendlyUrl.GetFriendlyNameById(cd.Id, cd.CompanyName)
                })
                .ToList();
        }


        private static string GetExchangeTickerSegment(string exchangeTickerComposite, bool getExchangeVsTicker)
        {
            var segmentIndex = getExchangeVsTicker ? 0 : 1;

            var mainExchangeTickerSegments = exchangeTickerComposite?.Split(':');

            return mainExchangeTickerSegments?.Length == 2 ? mainExchangeTickerSegments[segmentIndex] : null;
        }
    }
}
